<template>
  <div
    class="mb-4 flex rounded-xl px-2 py-6 dark:bg-slate-900 sm:px-4"
  >
    <VAvatar
      color="success"
      icon="tabler-brand-openai"
      style="margin-inline-end:8px"
    />

    <div class="flex max-w-3xl items-center rounded-xl">
      <p>
        <span v-for="response in msgHtml" :key="response.id">
          <span v-if="response.type == 'str'" v-html="response.content"></span>
          <AppCardCode
            v-else-if="response.type == 'code'"
            title="标题"
            code-language="js"
            :code="{ 'js': response.content }"
            no-padding
            show-code
            :show-title="false"
          />

        </span>
      </p>
    </div>

    
  </div>
</template>

<script setup>
import AppCardCode from '@/views/liteflow/logic/AppCardCode.vue';
import { onMounted } from 'vue';

const props = defineProps({
  record: {
    type: Object,
    required: true,
  },
})

const record = ref(props.record)

onMounted(()=>{
  callStreamEndpoint5()
})

const msgHtml = ref([]);

const closeEventSource = (eventSource) => {
  eventSource.close();
  // console.log(msgHtml)
}

const callStreamEndpoint5 = () => {
  const msg = record.value.msg;
  const eventSource = new EventSource('http://127.0.0.1:8090/chat/stream/generate?message=' + msg);

  let isInCodeBlock = false; // 用于跟踪是否在代码块内
  let tempMsg = ''; // 用于暂存截取的内容

  // 处理服务器发送的消息
  eventSource.onmessage = event => {
    const chatResponse = JSON.parse(event.data);
    // 如果数据中包含了 "STOP" 状态，关闭 EventSource 连接
    if (chatResponse.result.metadata.finishReason === "STOP") {
      closeEventSource(eventSource)
      return;
    }

    const content = chatResponse.result.output.content;

    // 将收到的内容逐字符处理
    for (let i = 0; i < content.length; i++) {
      if (!isInCodeBlock) {
        // 如果不在代码块内
        if (content[i] === '`') {
          // 如果遇到 ` 符号，表示开始代码块
          isInCodeBlock = true;
          if (tempMsg.length > 0) {
            // 如果 tempMsg 不为空，表示已经截取到内容，将其作为普通字符串存入数组中
            appendOrPush("str", tempMsg);
            tempMsg = ''; // 重置 tempMsg
          }
        } else {
          // 否则，将字符作为普通字符串存入数组中
          if (content[i] === '\n') {
            // 如果遇到换行符，则将当前内容作为新的对象推送到数组中
            appendOrPush("str", tempMsg);
            tempMsg = ''; // 重置 tempMsg
          } else {
            tempMsg += content[i];
          }
        }
      } else {
        // 如果在代码块内
        if (content[i] === '`') {
          // 如果遇到 ` 符号，表示结束代码块
          isInCodeBlock = false;
          // 将截取到的内容作为代码块存入数组中
          appendOrPush("code", tempMsg);
          tempMsg = ''; // 重置 tempMsg
        } else {
          // 否则，将字符作为代码块内容存入 tempMsg 中
          tempMsg += content[i];
        }
      }
    }
    // 处理最后的剩余内容
    if (tempMsg.length > 0) {
      appendOrPush(isInCodeBlock ? "code" : "str", tempMsg);
      tempMsg = ''; // 重置 tempMsg
    }
  };

  // 处理连接错误
  eventSource.onerror = error => {
    console.error('EventSource failed:', error);
    eventSource.close();
  };

  // 辅助函数：根据当前的类型追加或推送到 msgHtml 数组中
  function appendOrPush(type, content) {
    if (type === "code") {
      console.log(content)
    }
    if (type === "str" && content.includes("\n")) {
      // 如果是普通字符串且包含换行符，则将当前内容作为新的对象推送到数组中
      msgHtml.value.push({ type, content });
    } else if (msgHtml.value.length > 0 && msgHtml.value[msgHtml.value.length - 1].type === type) {
      // 否则，根据当前的类型追加或推送到数组中
      msgHtml.value[msgHtml.value.length - 1].content += content;
    } else {
      msgHtml.value.push({ type, content });
    }
  }
};

const callStreamEndpoint4 = () => {
  const msg = record.value.msg;
  const eventSource = new EventSource('http://127.0.0.1:8080/ai/generateStream?message=' + msg);

  let isInCodeBlock = false; // 用于跟踪是否在代码块内
  let tempMsg = ''; // 用于暂存截取的内容

  // 处理服务器发送的消息
  eventSource.onmessage = event => {
    const chatResponse = JSON.parse(event.data);
    // 如果数据中包含了 "STOP" 状态，关闭 EventSource 连接
    if (chatResponse.result.metadata.finishReason === "STOP") {
      eventSource.close();
      return;
    }

    const content = chatResponse.result.output.content;
    // 将收到的内容逐字符处理
    for (let i = 0; i < content.length; i++) {
      if (!isInCodeBlock) {
        // 如果不在代码块内
        if (content[i] === '`') {
          // 如果遇到 ` 符号，表示开始代码块
          isInCodeBlock = true;
          if (tempMsg.length > 0) {
            // 如果 tempMsg 不为空，表示已经截取到内容，将其作为普通字符串存入数组中
            appendOrPush("str", tempMsg);
            tempMsg = ''; // 重置 tempMsg
          }
        } else {
          // 否则，将字符作为普通字符串存入数组中
          tempMsg += content[i];
        }
      } else {
        // 如果在代码块内
        if (content[i] === '`') {
          // 如果遇到 ` 符号，表示结束代码块
          isInCodeBlock = false;
          // 将截取到的内容作为代码块存入数组中
          appendOrPush("code", tempMsg);
          tempMsg = ''; // 重置 tempMsg
        } else {
          // 否则，将字符作为代码块内容存入 tempMsg 中
          tempMsg += content[i];
        }
      }
    }
    // 处理最后的剩余内容
    if (tempMsg.length > 0) {
      appendOrPush(isInCodeBlock ? "code" : "str", tempMsg);
      tempMsg = ''; // 重置 tempMsg
    }
  };

  // 处理连接错误
  eventSource.onerror = error => {
    console.error('EventSource failed:', error);
    eventSource.close();
  };

  // 辅助函数：根据当前的类型追加或推送到 msgHtml 数组中
  function appendOrPush(type, content) {
    if (msgHtml.value.length > 0 && msgHtml.value[msgHtml.value.length - 1].type === type) {
      // 如果最后一个元素的类型与当前类型相同，则将内容追加到最后一个元素的内容中
      msgHtml.value[msgHtml.value.length - 1].content += content;
    } else {
      // 否则，将内容作为新的对象推送到数组中
      msgHtml.value.push({ type, content });
    }
  }
};
</script>
